home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / anwendungen / ispell-3.1.18bin / interfaces / guispell-1.1 / guispell.c < prev    next >
C/C++ Source or Header  |  1995-09-21  |  20KB  |  676 lines

  1. /*
  2.  *  This is GUISpell, the GadTool Front End for ISpell.
  3.  *  You must have AmigaOS release 2.04 (with ARexx running) and
  4.  *  `ISpell Version 3.1ljr with ARexx Server Mode, Thu Dec 27 04:16:35 1990'
  5.  *  or later.
  6.  *
  7.  *  Special thanks to Mike Schwartz for his PD GadTools Example
  8.  *  that was posted to alt.sources.amiga on `11 Nov 91 12:14:43 PST'
  9.  *  <mykes.8924@amiga0.SF-Bay.ORG>.  You will note that some chunks
  10.  *  below were ripped right out of his PD posting.  Thanks!
  11.  *  [Note: I don't like names that shout at me, so I removed all the
  12.  *   loud typedefs... :-]
  13.  *
  14.  *  Thanks to Eddy Carroll for Small.a (I now use cres.o, but thanks).
  15.  *  Thanks to Michael Jansson for smallIFFparse (a sub-set of IFFparse
  16.  *  that is Freely Redistributable) and sample code.
  17.  *
  18.  *  This program makes use of many 2.04 features and may be used as
  19.  *  an example of how to use iffparse.library, gadtools.library,
  20.  *  MinRexx (by Radical Eye Software, Thanks!), clipboard hooks,
  21.  *  public screen features and commodities.library.
  22.  *
  23.  *  This work is Copyright © 1991, 1992  Loren J. Rittle (rittle@comm.mot.com)
  24.  *  This software may be freely distributed and redistributed,
  25.  *  for non-commercial purposes, provided this notice is included.
  26.  *  You have the right to use the information contained within this
  27.  *  document/program in any way that you see fit, as long as you quote
  28.  *  this as the source of the information.  You have the right to compile
  29.  *  and run the program that is generated for any purpose.  All other
  30.  *  rights (most notably commercial ones) are reserved by the author.
  31.  *
  32.  *  DISCLAIMER:
  33.  * "This software is provided 'as-is', without warranty of any kind,
  34.  *  either expressed or implied.  In no event will I, Loren J. Rittle,
  35.  *  be liable for direct, indirect, incidental or consequential damages
  36.  *  or data loss resulting from the use or application of this software.
  37.  *  The entire risk as to the results and performance of this software
  38.  *  is assumed by you."
  39.  *
  40.  *  This program is distributed in the hope that it will be useful,
  41.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  42.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  43.  *
  44.  *  There, how's that for legal mush? :-)  Just trying to cover my...
  45.  *
  46.  *  Loren J. Rittle
  47.  *  rittle@comm.mot.com
  48.  *  Sun Dec 08 21:19:13 1991
  49.  */
  50.  
  51. #include <string.h>
  52. #pragma msg 148 ignore push
  53. #pragma msg 149 ignore push
  54. #pragma msg 61 ignore push
  55. #include <devices/clipboard.h>
  56. #include <proto/all.h>
  57. #pragma msg 149 pop
  58. #pragma msg 61 pop
  59. #include "libraries.h"
  60. #include "error.h"
  61. #include "minrexx.h"
  62. #include "textclip.h"
  63.  
  64. extern long __builtin_getreg (int);
  65. extern void __builtin_putreg (int, long);
  66. #define REG_A4 12
  67.  
  68. extern char *_ProgramName;
  69.  
  70. #define VERSION "GUISpell 1.1 (26.9.92)"
  71. #define NICE_VERSION "GUISpell-1.1 (" __DATE__ " " __TIME__ ")"
  72.  
  73. static char Version_ID[] = "$VER: " VERSION;
  74.  
  75. char *listText[512];
  76. char *initListText[] =
  77. {
  78.   NICE_VERSION,
  79.   "This is a freely distributable version",
  80.   "Copyright \xa9 1991, 1992  Loren J. Rittle",
  81.   "",
  82.   "GUISpell is the premier GUI front-end",
  83.   "to ISpell 3.3LJR (or later) with ARexx",
  84.   "Server Mode, for AmigaOS Release 2.04.",
  85.   "",
  86.   "If you use this software, please mail",
  87.   "the author at rittle@comm.mot.com, so I",
  88.   "can inform you of bugs and upgrades.",
  89.   0,
  90. };
  91.  
  92. struct List lvList;
  93. struct Gadget *gList;
  94. struct Window *window;
  95. struct Screen *screen;
  96. APTR vi;
  97. void *memory;
  98. struct IOClipReq *ClipReq;
  99. struct MsgPort *ClipPort;
  100. struct Hook ClipHook;
  101. struct ClipHookMsg ClipHookMsg = {0, CMD_UPDATE, 0};
  102. struct Task *Task;
  103. ULONG ClipAlertSignalNum = -1;
  104. BOOL done;
  105. int auto_clip;
  106. int lookup_type;
  107.  
  108. struct TextAttr topaz80 = {"topaz.font", 8, 0, 0};
  109.  
  110. char *cycleText[] = {"Spell", "Reg exp", "Exact", 0};
  111.  
  112. struct TagItem nullTags[] = {TAG_DONE, 0};
  113. struct TagItem cycleTags[] = {GTCY_Labels, (int) &cycleText[0], GTBB_Recessed, FALSE, TAG_DONE, 0};
  114. struct TagItem listviewTags[] = {GTLV_Labels, (int) &lvList, GTLV_ReadOnly, FALSE, GTLV_ScrollWidth, 16, TAG_DONE, 0};
  115. struct TagItem stringTags[] = {GTTX_CopyText, TRUE, GTTX_Border, FALSE, TAG_DONE, 0};
  116.  
  117. struct
  118. {
  119.   struct TagItem *tags;
  120.   ULONG kind;
  121.   UWORD left, top, width, height;
  122.   ULONG flags;
  123.   char *text;
  124.   struct Gadget *object;
  125. } gads[] =
  126. {
  127.   {cycleTags, CYCLE_KIND, 121, 13, 90, 12, NG_HIGHLABEL, "Lookup Style:", 0},
  128.   {nullTags, CHECKBOX_KIND, 310, 13, 80, 12, NG_HIGHLABEL, "Auto-Clip:", 0},
  129.   {listviewTags, LISTVIEW_KIND, 20, 44, 360, 92, NG_HIGHLABEL | PLACETEXT_ABOVE, "", 0},
  130.   {nullTags, BUTTON_KIND, 234, 27, 81, 12, NG_HIGHLABEL | PLACETEXT_IN,"From Clip", 0},
  131.   {nullTags, BUTTON_KIND, 325, 27, 65, 12, NG_HIGHLABEL | PLACETEXT_IN,"To Clip", 0},
  132.   {nullTags, BUTTON_KIND, 350, 13, 40, 12, NG_HIGHLABEL | PLACETEXT_IN,"Add", 0},
  133.   {stringTags, STRING_KIND, 10, 27, 180, 12, NG_HIGHLABEL, "", 0},
  134.   {nullTags, BUTTON_KIND, 200, 27, 24, 12, NG_HIGHLABEL | PLACETEXT_IN,"Do", 0},
  135.   {0, 0, 0, 0, 0, 0, 0, 0, 0},
  136. };
  137.  
  138. #define    LOOKUP_STYLE_ID    0
  139. #define    AUTO_CLIP_ID    1
  140. #define    WORD_LIST_ID    2
  141. #define FROM_CLIP_ID    3
  142. #define TO_CLIP_ID    4
  143. #define ADD_WORD_ID    5
  144. #define USER_WORD_ID    6
  145. #define DO_ID        7
  146.  
  147. int main (int argc, char *argv[]);
  148. void SubmitCheckRequest (int type, char *word);
  149. void UpdateList (struct RexxMsg *msg);
  150. void ProcessGadget (UWORD id, UWORD code);
  151. void GadgetUp (struct IntuiMessage *m);
  152. void *CreateList (struct List *list, char *array[]);
  153. struct Gadget *CreateGadgets (void);
  154. void OpenAll (void);
  155. void CloseAll (void);
  156. void rexxdisp (struct RexxMsg *msg, struct rexxCommandList *dat, char *p);
  157.  
  158. void rexxjump (struct RexxMsg *msg, char *p);
  159. void rexxcheck (struct RexxMsg *msg, char *p);
  160. /* void rexxquickcheck (struct RexxMsg *msg, char *p);
  161. //void rexxlookup (struct RexxMsg *msg, char *p);
  162. //void rexxcheckmode (struct RexxMsg *msg, char *p);
  163. //void rexxautomode (struct RexxMsg *msg, char *p);
  164. //void rexxzoommode (struct RexxMsg *msg, char *p);
  165. //void rexxzoomwindow (struct RexxMsg *msg, char *p); */
  166. void rexxcurrenttext (struct RexxMsg *msg, char *p);
  167. void rexxcheckcallbackhook (struct RexxMsg *msg, char *p);
  168. void invokerexxcheckcallbackhook (void);
  169. void rexxversion (struct RexxMsg *msg, char *p);
  170. void rexxexit (struct RexxMsg *msg, char *p);
  171.  
  172. struct rexxCommandList rcl[] =
  173. {
  174.   {"check", &rexxcheck},
  175.   {"jump", &rexxjump},
  176.   {"currenttext", &rexxcurrenttext},
  177.   {"checkcallbackhook", &rexxcheckcallbackhook},
  178.   {"version", &rexxversion},
  179.   {"exit", &rexxexit},
  180.   {NULL, NULL}
  181. };
  182.  
  183. /* This is really kludged up to get it to work under SAS/C 5.10b
  184.    with cres.o.  This code is unportable between compilers and
  185.    in fact may fail with other versions of SAS/C.  */
  186. ULONG __asm ClipChange (register __a0 struct Hook *hook,
  187.             register __a4 void *junk)
  188. {
  189.   __builtin_putreg (REG_A4, (long) hook->h_SubEntry);
  190.   Signal (Task, 1 << ClipAlertSignalNum);
  191.   return 0;
  192. }
  193.  
  194. int main (int argc, char *argv[])
  195. {
  196.   long rexxbit;
  197.  
  198.   OnError (&CloseAll);
  199.  
  200.   {
  201.     int i;
  202.  
  203.     for (i = 0; initListText[i]; i++)
  204.       listText[i] = initListText[i];
  205.   }
  206.  
  207.   OpenAll ();
  208.  
  209.   if (!(rexxbit = upRexxPort ("GUISpell", rcl, 0, &rexxdisp)))
  210.     Error ("ss", _ProgramName, ": MinRexx had a problem.\n");
  211.  
  212.   while (!done)
  213.     {
  214.       struct IntuiMessage *m;
  215.       long returnbits = Wait ((1 << window->UserPort->mp_SigBit) | rexxbit |
  216.                   (1 << ClipAlertSignalNum) | SIGBREAKF_CTRL_C);
  217.  
  218.       if (returnbits & SIGBREAKF_CTRL_C)
  219.     done = 1;
  220.       if (returnbits & rexxbit)
  221.     dispRexxPort ();
  222.       if ((returnbits & (1 << ClipAlertSignalNum)) && auto_clip)
  223.     {
  224.           char buffer[256];
  225.  
  226.           if (TextFromClip (buffer, 256) && !strchr (buffer, ' '))
  227.         {
  228.           static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  229.  
  230.           tags[0].ti_Data = (ULONG) buffer;
  231.           GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  232.           SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  233.         }
  234.     }
  235.       if (returnbits & (1 << window->UserPort->mp_SigBit))
  236.         while (m = GT_GetIMsg (window->UserPort))
  237.       {
  238.         struct IntuiMessage msg = *m;
  239.         GT_ReplyIMsg (m);
  240.  
  241.         switch (msg.Class)
  242.           {
  243.           case IDCMP_GADGETUP:
  244.         if (msg.Code == 0x09)
  245.           {
  246.           }
  247.         if (msg.Code == 0x5f)
  248.           {
  249.           }
  250.         else
  251.           ProcessGadget (((struct Gadget *) msg.IAddress)->GadgetID, msg.Code);
  252.             break;
  253.  
  254.           case IDCMP_REFRESHWINDOW:
  255.             GT_BeginRefresh (window);
  256.             GT_EndRefresh (window, TRUE);
  257.             break;
  258.  
  259.           case IDCMP_CLOSEWINDOW:
  260.             done = 1;
  261.             break;
  262.  
  263.           default:
  264.             break;
  265.           }
  266.       }
  267.     }
  268.  
  269.   CloseAll ();
  270.   return 0;
  271. }
  272.  
  273. void SubmitCheckRequest (int lookup_type, char *word)
  274. {
  275.   char buffer[256];
  276.   static char *rexxcommandname[] = {"check ", "lookup ", "quickcheck ", "add "};
  277.  
  278.   if (lookup_type > 3)
  279.     {
  280.       DisplayBeep (0);
  281.       return;
  282.     }
  283.   strcpy (buffer, rexxcommandname[lookup_type]);
  284.   strncat (buffer, word, 240);
  285.   if (!sendSimpleCmd (buffer, "IRexxSpell", &UpdateList, NULL, NULL, NULL))
  286.     DisplayBeep (0);
  287. }
  288.  
  289. void UpdateList (struct RexxMsg *msg)
  290. {
  291.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  292.   static struct TagItem tags2[] = {GTLV_Labels, (int) &lvList, GTLV_Top, 0, TAG_DONE, 0};
  293.   static char buffer[513];
  294.  
  295.   if (!msg->rm_Result1 && msg->rm_Result2)
  296.     {
  297.       GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  298.  
  299.       if (((struct RexxArg *) (msg->rm_Result2-8))->ra_Length > 512)
  300.     {
  301.           memcpy (buffer, (char *) msg->rm_Result2, 512);
  302.       buffer[512] = '\0';
  303.     }
  304.       else
  305.     {
  306.           memcpy (buffer, (char *) msg->rm_Result2,
  307.           ((struct RexxArg *) (msg->rm_Result2-8))->ra_Length);
  308.           buffer[((struct RexxArg *) (msg->rm_Result2-8))->ra_Length] = '\0';
  309.     }
  310.  
  311.       {
  312.     int a, b = 0;
  313.  
  314.     listText[b++] = &buffer[0];
  315.     for (a = 0; buffer[a]; a++)
  316.       if (buffer[a] == ' ')
  317.         {
  318.           if (buffer[a+1])
  319.         listText[b++] = &buffer[a+1];
  320.           buffer[a] = '\0';
  321.         }
  322.     listText[b] = 0;
  323.       }
  324.       
  325.       if (memory)
  326.         {
  327.           FreeVec (memory);
  328.           memory = 0;
  329.         }
  330.       memory = CreateList (&lvList, &listText[0]);
  331.  
  332.       GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags2);
  333.  
  334.       DeleteArgstring ((char *) msg->rm_Result2);
  335.     }
  336.   else
  337.     DisplayBeep (0);
  338. }
  339.  
  340. void ProcessGadget (UWORD id, UWORD code)
  341. {
  342.   switch (id)
  343.     {
  344.     case LOOKUP_STYLE_ID:
  345.       lookup_type = code;
  346.       break;
  347.     case AUTO_CLIP_ID:
  348.       auto_clip = gads[id].object->Flags & SELECTED;
  349.       break;
  350.     case WORD_LIST_ID:
  351.      {
  352.       static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  353.       tags[0].ti_Data = (ULONG) listText[code];
  354.       GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  355.       if (auto_clip)
  356.     TextToClip (((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  357.       invokerexxcheckcallbackhook ();
  358.       break;
  359.      }
  360.     case FROM_CLIP_ID:
  361.      {
  362.       char buffer[256];
  363.  
  364.       if (TextFromClip (buffer, 256))
  365.     {
  366.       static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  367.  
  368.       tags[0].ti_Data = (ULONG) buffer;
  369.       GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  370.       if (!strchr (buffer, ' '))
  371.         SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  372.     }
  373.       break;
  374.      }
  375.     case TO_CLIP_ID:
  376.       TextToClip (((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  377.       break;
  378.     case ADD_WORD_ID:
  379.       SubmitCheckRequest (3, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  380.       break;
  381.     case DO_ID:
  382.     case USER_WORD_ID:
  383.       SubmitCheckRequest (lookup_type, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  384.       break;
  385.     default:
  386.       break;
  387.     }
  388. }
  389.  
  390. void *CreateList (struct List *list, char *array[])
  391. {
  392.   short i;
  393.   struct Node *np, *start_np;
  394.  
  395.   NewList (list);
  396.   for (i = 0; array[i]; i++)
  397.     ;
  398.   start_np = AllocVec (sizeof (struct Node) * i, 0);
  399.   if (!start_np)
  400.     Error ("ss", _ProgramName, ": No free memory!\n");
  401.  
  402.   for (i = 0, np = start_np; array[i]; i++, np++)
  403.     {
  404.       np->ln_Name = (APTR) array[i];
  405.       np->ln_Pri = 0;
  406.       AddTail (list, np);
  407.     }
  408.   return start_np;
  409. }
  410.  
  411. struct Gadget *CreateGadgets (void)
  412. {
  413.   struct Gadget *gadget, *glist = 0;
  414.   short i;
  415.   struct NewGadget ng;
  416.  
  417.   gadget = CreateContext (&glist);
  418.   if (!gadget)
  419.     Error ("ss", _ProgramName, ": Can't CreateContext\n");
  420.   for (i = 0; gads[i].tags; i++)
  421.     {
  422.       ng.ng_GadgetID = i;
  423.       ng.ng_TextAttr = &topaz80;
  424.       ng.ng_VisualInfo = vi;
  425.       ng.ng_LeftEdge = gads[i].left;
  426.       ng.ng_TopEdge = gads[i].top;
  427.       ng.ng_Width = gads[i].width;
  428.       ng.ng_Height = gads[i].height;
  429.       ng.ng_GadgetText = gads[i].text;
  430.       ng.ng_Flags = gads[i].flags;
  431.       gads[i].object = gadget = CreateGadgetA (gads[i].kind, gadget, &ng, gads[i].tags);
  432.       if (!gadget)
  433.     Error ("ss", _ProgramName, ": Can't CreateGadget\n");
  434.     }
  435.   return glist;
  436. }
  437.  
  438. void OpenAll (void)
  439. {
  440.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  441.   static WORD zoom_data[4] = {0, 0, 400, 43};
  442.   static struct TagItem wtags[] =
  443.     {
  444.       WA_Left, 0, WA_Top, 0, WA_Width, 400, WA_Height, 143,
  445.       WA_MinWidth, 400, WA_MinHeight, 43, WA_MaxWidth, -1, WA_MaxHeight, -1,
  446.       WA_DetailPen, 0, WA_BlockPen, 3, WA_IDCMP, 
  447.       IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|BUTTONIDCMP|CYCLEIDCMP|LISTVIEWIDCMP,
  448.       WA_Gadgets, 0 /*set below*/, WA_PubScreen, 0, /*set below*/
  449.       WA_Title, (ULONG)"GUISpell-1.1", WA_SuperBitMap, 0,
  450.       WA_SizeGadget, FALSE, WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  451.       WA_CloseGadget, TRUE, WA_Backdrop, FALSE, WA_ReportMouse, FALSE,
  452.       WA_Borderless, FALSE, WA_Activate, TRUE, WA_RMBTrap, FALSE,
  453.       WA_SimpleRefresh, TRUE, WA_Zoom, (ULONG)zoom_data, WA_RMBTrap, TRUE, TAG_DONE, 0
  454.     };
  455.  
  456.   OpenLibraries ();
  457.  
  458.   screen = LockPubScreen ("CygnusEdScreen1");
  459.   if (!screen)
  460.     screen = LockPubScreen ("Workbench");
  461.   if (!screen)
  462.     Error ("ss", _ProgramName, ": Can't Lock WB Screen!\n");
  463.  
  464.   vi = GetVisualInfoA (screen, TAG_DONE);
  465.   if (!vi)
  466.     Error ("ss", _ProgramName, ": Can't GetVisualInfoA\n");
  467.  
  468.   memory = CreateList (&lvList, &listText[0]);
  469.   gList = CreateGadgets ();
  470.   wtags[11].ti_Data = (ULONG) gList;
  471.   wtags[12].ti_Data = (ULONG) screen;
  472.   window = OpenWindowTagList (NULL, wtags);
  473.   UnlockPubScreen (0, screen);
  474.   if (!window)
  475.     Error ("ss", _ProgramName, ": Can't open window\n");
  476.   GT_RefreshWindow (window, NULL);
  477.   GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  478.  
  479.   Task = FindTask (0);
  480.   if ((ClipAlertSignalNum = AllocSignal (-1)) == -1)
  481.     Error ("ss", _ProgramName, ": Can't get a signal\n");
  482.   if (!(ClipPort = CreatePort (0L, 0L)))
  483.     Error ("ss", _ProgramName, ": Can't create port\n");
  484.   if (!(ClipReq = (struct IOClipReq *) CreateExtIO (ClipPort, sizeof (*ClipReq))))
  485.     Error ("ss", _ProgramName, ": Can't create ExtIO\n");
  486.   if (OpenDevice ("clipboard.device", 0L, (struct IORequest *) ClipReq, 0L))
  487.     Error ("ss", _ProgramName, ": Can't open clipboard device\n");
  488.   ClipReq->io_Command = CBD_CHANGEHOOK;
  489.   ClipReq->io_Length = 1;
  490.   ClipReq->io_Data = (void *) &ClipHook;
  491.   ClipHook.h_Entry = &ClipChange;
  492.   ClipHook.h_SubEntry = (ULONG (*)()) __builtin_getreg (REG_A4);
  493.   ClipHook.h_Data = &ClipHookMsg;
  494.   if (DoIO ((struct IORequest *) ClipReq))
  495.     Error ("ss", _ProgramName, ": Can't install clipboard hook\n");
  496. }
  497.  
  498. void CloseAll (void)
  499. {
  500.   struct IntuiMessage *msg;
  501.  
  502.   if (ClipReq)
  503.     {
  504.       ClipReq->io_Command = CBD_CHANGEHOOK;
  505.       ClipReq->io_Length = 0;
  506.       ClipReq->io_Data = (void *) &ClipHook;
  507.       if (DoIO ((struct IORequest *) ClipReq))
  508.         Warning ("ss", _ProgramName, ": Can't deinstall clipboard hook (crash soon... :-)\n");
  509.       if (ClipReq->io_Device)
  510.         CloseDevice ((struct IORequest *)ClipReq);
  511.       DeleteExtIO ((struct IORequest *)ClipReq);
  512.     }
  513.   if (ClipPort)
  514.     DeletePort (ClipPort);
  515.   if (ClipAlertSignalNum != -1)
  516.     FreeSignal (ClipAlertSignalNum);
  517.  
  518.   dnRexxPort ();
  519.  
  520.   if (window)
  521.     {
  522.       while (msg = (struct IntuiMessage *) GT_GetIMsg (window->UserPort))
  523.     GT_ReplyIMsg (msg);
  524.       CloseWindow (window);
  525.       window = 0;
  526.     }
  527.  
  528.   if (vi)
  529.     {
  530.       FreeVisualInfo (vi);
  531.       vi = 0;
  532.     }
  533.  
  534.   if (gList)
  535.     {
  536.       FreeGadgets (gList);
  537.       gList = 0;
  538.     }
  539.  
  540.   if (memory)
  541.     {
  542.       FreeVec (memory);
  543.       memory = 0;
  544.     }
  545.  
  546.   CloseLibraries ();
  547. }
  548.  
  549. void rexxdisp (struct RexxMsg *msg, struct rexxCommandList *dat, char *p)
  550. {
  551.   (*(dat->userdata)) (msg, p);
  552. }
  553.  
  554. void rexxjump (struct RexxMsg *msg, char *p)
  555. {
  556.   struct IntuiMessage *Imsg;
  557.   static struct TagItem tags[] = {GTLV_Labels, ~0, TAG_DONE, 0};
  558.   static WORD zoom_data[4] = {0, 0, 400, 43};
  559.   static struct TagItem wtags[] =
  560.     {
  561.       WA_Left, 0, WA_Top, 0, WA_Width, 400, WA_Height, 143,
  562.       WA_MinWidth, 400, WA_MinHeight, 43, WA_MaxWidth, -1, WA_MaxHeight, -1,
  563.       WA_DetailPen, 0, WA_BlockPen, 3, WA_IDCMP, 
  564.       IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|BUTTONIDCMP|CYCLEIDCMP|LISTVIEWIDCMP,
  565.       WA_Gadgets, 0 /*set below*/, WA_PubScreen, 0, /*set below*/
  566.       WA_Title, (ULONG)"GUISpell-1.1", WA_SuperBitMap, 0,
  567.       WA_SizeGadget, FALSE, WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  568.       WA_CloseGadget, TRUE, WA_Backdrop, FALSE, WA_ReportMouse, FALSE,
  569.       WA_Borderless, FALSE, WA_Activate, TRUE, WA_RMBTrap, FALSE,
  570.       WA_SimpleRefresh, TRUE, WA_Zoom, (ULONG)zoom_data, WA_RMBTrap, TRUE, TAG_DONE, 0
  571.     };
  572.  
  573.   if (window)
  574.     {
  575.       while (Imsg = (struct IntuiMessage *) GT_GetIMsg (window->UserPort))
  576.     GT_ReplyIMsg (Imsg);
  577.       CloseWindow (window);
  578.       window = 0;
  579.     }
  580.  
  581.   if (vi)
  582.     {
  583.       FreeVisualInfo (vi);
  584.       vi = 0;
  585.     }
  586.  
  587.   if (gList)
  588.     {
  589.       FreeGadgets (gList);
  590.       gList = 0;
  591.     }
  592.  
  593.  
  594.   screen = LockPubScreen (p);
  595.   if (!screen)
  596.     screen = LockPubScreen ("Workbench");
  597.   if (!screen)
  598.     Error ("ss", _ProgramName, ": Can't Lock WB Screen!\n");
  599.  
  600.   vi = GetVisualInfoA (screen, TAG_DONE);
  601.   if (!vi)
  602.     Error ("ss", _ProgramName, ": Can't GetVisualInfoA\n");
  603.  
  604.   gList = CreateGadgets ();
  605.   wtags[11].ti_Data = (ULONG) gList;
  606.   wtags[12].ti_Data = (ULONG) screen;
  607.   window = OpenWindowTagList (NULL, wtags);
  608.   UnlockPubScreen (0, screen);
  609.   if (!window)
  610.     Error ("ss", _ProgramName, ": Can't open window\n");
  611.   GT_RefreshWindow (window, NULL);
  612.   GT_SetGadgetAttrsA (gads[WORD_LIST_ID].object, window, NULL, tags);
  613. }
  614.  
  615. void rexxcheck (struct RexxMsg *msg, char *p)
  616. {
  617.   static struct TagItem tags[] = {GTST_String, 0, TAG_DONE, 0};
  618.  
  619.   tags[0].ti_Data = (ULONG) p;
  620.   GT_SetGadgetAttrsA(gads[USER_WORD_ID].object, window, NULL, tags);
  621.   SubmitCheckRequest (0, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  622.   replyRexxCmd (msg, 0L, 0L, "ok");
  623. }
  624.  
  625. void rexxcurrenttext (struct RexxMsg *msg, char *p)
  626. {
  627.   replyRexxCmd (msg, 0L, 0L, ((struct StringInfo *)gads[USER_WORD_ID].object->SpecialInfo)->Buffer);
  628. }
  629.  
  630. char checkcallbackhookcode[512];
  631.  
  632. void rexxcheckcallbackhook (struct RexxMsg *msg, char *p)
  633. {
  634.   if (!checkcallbackhookcode[0] || (strlen (p) < sizeof (checkcallbackhookcode)))
  635.     {
  636.       strcpy (checkcallbackhookcode, p);
  637.       replyRexxCmd (msg, 0L, 0L, "installed");
  638.     }
  639.   else
  640.     replyRexxCmd (msg, 0L, 0L, "notinstalled");
  641. }
  642.  
  643. void invokerexxcheckcallbackhook (void)
  644. {
  645.   if (checkcallbackhookcode[0] && !asyncRexxCmd (checkcallbackhookcode))
  646.     DisplayBeep (0);
  647.   checkcallbackhookcode[0] = '\0';
  648. }
  649.  
  650. void rexxversion (struct RexxMsg *msg, char *p)
  651. {
  652.   char buf[512];
  653.   int bufend = strlen(Version_ID+6);
  654.   int namesize;
  655.   int i;
  656.  
  657.   strcpy(buf, Version_ID+6);
  658.   buf[bufend++] = '\n';
  659.   for (i = 0; rcl[i].name != NULL; i++)
  660.     {
  661.       namesize = strlen(rcl[i].name);
  662.       if ((namesize + bufend) > 511)
  663.     break;
  664.       strcpy (&(buf[bufend++]), " ");
  665.       strcpy (&(buf[bufend]), rcl[i].name);
  666.       bufend += namesize;
  667.     }
  668.   replyRexxCmd (msg, 0L, 0L, buf);
  669. }
  670.  
  671. void rexxexit (struct RexxMsg *msg, char *p)
  672. {
  673.   done = 1;
  674.   replyRexxCmd (msg, 0L, 0L, "bye");
  675. }
  676.